﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spinning.Spinning.Level;
using Microsoft.Xna.Framework;
using Spinning.Spinning.Unitity;
using Spinning.Spinning.Interface;
using Microsoft.Xna.Framework.Input.Touch;
using System.Net;
using Microsoft.Phone.Info;
using Microsoft.Devices.Sensors;
using com.google.zxing;
using com.google.zxing.common;
using com.google.zxing.qrcode;
using Microsoft.Xna.Framework.Graphics;

namespace Spinning.Spinning.Entity.Scenes
{
    class UdpTestScene : PracticeScene, ITouchable
    {
        public delegate void TouchEventHandler(BaseEntity entity, TouchLocation touchLocation);
        public TouchEventHandler OnTouchEvent, OnReleaseEvent, OnHoldEvent;

        String ID;
        private UdpAnySourceMulticastChannel Channel { get; set; }
        TextEntity te;
        Vector3 _accelReading = new Vector3();
        Vector3 _accelReadingEnemy = new Vector3();
        PracticePlayer Enemy;

        bool isPress;

        public UdpTestScene()
            : base()
        {
            isPress = false;
            Game1._acceleMeter.CurrentValueChanged += GSensorChanged;
            try
            {
                Game1._acceleMeter.Start();
            }
            catch (AccelerometerFailedException e) { throw e; }
            catch (UnauthorizedAccessException e) { throw e; }
        }

        void GSensorChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
        {
            _accelReading.X = (float)e.SensorReading.Acceleration.X;
            _accelReading.Y = -(float)e.SensorReading.Acceleration.Y;
            _accelReading.Z = (float)e.SensorReading.Acceleration.Z;
        }

        public override void OnLoad()
        {
            base.OnLoad();
            te = new TextEntity();
            ResourceManager.ContentRoot = "";
            te.fontString = "TestFont";
            te.OnLoad();
            te.Origin = new Vector2(0.5f);
            te.Position = new Vector2(200, 200);
            te.Color = Color.Blue;
            //te.Alpha = 0;
            te.ZIndex = Constants.debugText;
            //Attach(te);
            te.Value = "test123";
            TouchManager.RegisteTouchArea(this);

            Enemy = new PracticePlayer();
            Enemy.textureName = "spinning";
            Enemy.OnLoad();
            Enemy.SetAnimation(Constants.playerAnimationFrame);
            Enemy.OnCreatBody(World, PhysicConnectManager);
            Enemy.BodyPosiotion = new Vector2(240, 200);
            this.Attach(Enemy);

            this.Channel = new UdpAnySourceMulticastChannel(IPAddress.Parse("224.0.1.100"), 3000);
            this.Channel.AfterOpen += new EventHandler(Channel_AfterOpen);
            this.Channel.BeforeClose += new EventHandler(Channel_BeforeClose);
            this.Channel.PacketReceived += new EventHandler<UdpPacketReceivedEventArgs>(Channel_PacketReceived);

            this.Channel.Open();

            ID = GetDeviceUniqueID();
            // QRcode
            int QRsize = 400;
            QRSprite QR = new QRSprite("test123 ,hahaha", new Point(QRsize, QRsize));
            QR.Position = new Vector2(240 - QRsize / 2, 400 - QRsize/2);
            QR.ZIndex = Constants.debugText;
            this.Attach(QR);
            //
        }

        public static String GetDeviceUniqueID()
        {
            object DeviceUniqueID;

            byte[] DeviceIDbyte = null;

            if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out DeviceUniqueID))

                DeviceIDbyte = (byte[])DeviceUniqueID;

            string DeviceID = Convert.ToBase64String(DeviceIDbyte);

            return DeviceID;
        }

        protected override void UpdateSelf(GameTime gameTime)
        {
            base.UpdateSelf(gameTime);
            //enemyLuncher.OnUpdate(gameTime);
            Player.Accelerometer = _accelReading;
            this.Channel.Send("{0},{1},{2},{3},", ID, _accelReading.X, _accelReading.Y, _accelReading.Z);
        }

        public bool Contain(Vector2 position)
        {
            Vector2 topLeft = Position - Origin * new Vector2(Size.X, Size.Y) * Scale;
            Vector2 rightDown = topLeft + new Vector2(Size.X, Size.Y) * Scale;
            return (position.X > topLeft.X && position.X < rightDown.X && position.Y > topLeft.Y && position.Y < rightDown.Y);
        }

        public void OnTouch(TouchLocation touchLocation)
        {
            isPress = true;
            if (OnTouchEvent != null)
                OnTouchEvent(this, touchLocation);
        }

        public void OnRelease(TouchLocation touchLocation)
        {
            isPress = false;
            if (OnReleaseEvent != null)
                OnReleaseEvent(this, touchLocation);
        }

        public void OnHold(TouchLocation touchLocation)
        {
            //this.Channel.Send("{0},{1},{2},{3},", ID, _accelReading.X, _accelReading.Y, _accelReading.Z);
            
            if (OnHoldEvent != null)
                OnHoldEvent(this, touchLocation);
        }

        void Channel_BeforeClose(object sender, EventArgs e)
        {
            this.Channel.Send("END,{0}, leaves the UDP Multicast chat", ID);
        }

        void Channel_AfterOpen(object sender, EventArgs e)
        {
            this.Channel.Send("BEGIN,{0}, enters the UDP Multicast chat", ID);
        }

        //沒用到Channel.close(); 範例也沒

        void Channel_PacketReceived(object sender, UdpPacketReceivedEventArgs e)
        {
            //if(e.Message.Length!=0)
            //te.Value = e.Message;

            string[] temp;

            temp = e.Message.Split(',');

            if (temp[0] == "END")
            {
                te.Value = temp[0] + temp[1];
                return;
            }

            if (temp.Length > 3 && temp[0] == ID)
            {
                return;
            }

            if (temp.Length > 3)
            {
                te.Value = "Received (X,Y,Z): (" + temp[1] + "," + temp[2] + "," + temp[3]+")";
                _accelReadingEnemy.X = float.Parse(temp[1]);
                _accelReadingEnemy.Y = float.Parse(temp[2]);
                _accelReadingEnemy.Z = float.Parse(temp[3]);
                Enemy.Accelerometer = _accelReadingEnemy;
            }
        }

        public override BaseScene Clone()
        {
            BaseScene scene = new UdpTestScene();
            scene.Size = new Vector2(Constants.Window_Width, Constants.Window_Height);
            scene.OnLoad();
            scene.SortChildren();
            return scene;
        }
    }
}
